#!/usr/bin/env python
# -*- coding: utf-8 -*- 

'''
authors: Fábio Martins nº6041 and Miguel Travassos nº6312
'''


import Tkinter as tk
from Tkinter import *
import ttk
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from readExcel_WriteDataBase import*
import tkMessageBox
import tkFileDialog
from statistics import*
from saveCsv import*
from makeGraphics import*



class main(object):
    def __init__(self,root):

        #Tamanho da janela
        root.geometry("700x500")
    

        # frame principal da janela, onde vão ser colocadas todas as frames do programa
        self.container = Frame(root)
        self.container.pack(side="top", fill="both", expand=True)
        self.container.grid_rowconfigure(0, weight=1)
        self.container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (startProgFrame,initFrame, frameStatistics, graphFrame):
            #coloca todas as frames que vao ser adicionadas a frame principal num dicionario
            frame = F(self.container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")

        self.show_frame(startProgFrame)

    def show_frame(self, frame):
        '''Funçao que mostra a frame na janela'''

        showFrame = self.frames[frame]
        showFrame.tkraise()
        pass


class startProgFrame(Frame):
    """Frame que contem o que ira aparecer no inicio do programa"""
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

        #inicializar a frame principal
        self.controller = controller
        #inicializar a classe WriteFilesInDataBase
        self.writeFilesInDataBase = WriteFilesInDataBase()

        #Label que contem o titulo do trabalho
        self.label = Label(self, text=" \n Análise de colocações \n no \n Ensino Superior \n ", font=('times', 15, 'bold'), bg='blue',width=50)
        self.label.pack()

        
        #Butao que cria a base de dados 
        self.createBD_Button = Button(self, text ="Criar Base de Dados", command=self.event_createBD)
        self.createBD_Button.pack()

        #label que contem o nome dos autores do programa
        self.labelAutores = Label(self, text=" \n Autor: Fábio Martins nº6041 \n \n Autor: Miguel Travassos nº6312 \n ",font=('times',10, 'bold'))
        self.labelAutores.pack()

    def event_createBD(self):
        """ 
        Evento do butao self.createBD_Button que cria a base de dados quando é chamado
        """
        try:
            #cria a base de dados
            self.writeFilesInDataBase.dataBaseCreate()
            #insere os dados na base de dados
            self.writeFilesInDataBase.insertDataInDataBase()
            tkMessageBox.showinfo("SUCESSO", "BASE DE DADOS CRIADA COM SUCESSO")

            #chama a frame initFrame quando a base de dados é criada com sucesso
            self.controller.show_frame(initFrame)
            
            pass
        except Exception, e:
            tkMessageBox.showinfo("ERRO", "O FICHEIRO cna131fresultados.xls NAO SE ENCONTRA NA DIRECTORIA DO CODIGO FONTE")
            raise
        
        
class initFrame(Frame):
    """ Frame que aparece quando a base de dados é criada, contem dois butoes, estatisticas e graficos """
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)


        #frame que vai conter os dois butoes, para visualizar estatisticas e de graficos
        self.frameOptions=Frame(self)
        self.frameOptions.pack()

        
        #buttao  que mostra a frame das estatisticas
        self.statisticsButton = Button(self.frameOptions, text ="Estatisticas",width=25, command=lambda: controller.show_frame(frameStatistics))
        self.statisticsButton.pack(side=LEFT)

        
        #butao que mostra a frame dos graficos
        self.graphicButton = Button(self.frameOptions, text ="Gráficos",width=25, command=lambda: controller.show_frame(graphFrame))
        self.graphicButton.pack(side=LEFT)


class frameStatistics(Frame):
    """ Frame que vai conter todas as estatisticas, selecionaveis a partir de uma combobox,visionadas num ttK.tree e com opçao de salvar onde o utilizador quiser"""
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)
        #inicializaçao da classe que faz as estatisticas
        self.statisticsClass = statisticsClass()

        #Criar a frame que vai conter todos os widgets criados em baixo
        self.Frame = initFrame(self,controller)
        self.Frame.pack()

        #Frame que vai conter a combombox,a label e o botao de gerar estatistica
        self.frameButtons = Frame(self)
        self.frameButtons.pack(side=TOP)

        #Label Estatisticas a anteceder a combobox que contem o nome das estatisticas
        self.labelStatistics = Label(self.frameButtons, text="Estatisticas:",font=('times',10, 'bold'))
        self.labelStatistics.pack(side = LEFT)

        #array com o nome das estatisticas a apresentar pela combobox
        self.optionsCombomBox = ['o numero de alunos colocados por instituicao', 'o numero de alunos colocados por distrito', 'a permilagem de alunos colocados por distrito','a percentagem de alunos colocados por instituicao em relacao a todos os alunos colocados','o numero de vagas por colocar por instituicao','o numero de vagas por colocar por distrito']
        
        #combobox que vai conter o nome das estatisticas
        self.comboBox = ttk.Combobox(self.frameButtons, textvariable="valueStatistics", state='readonly',values=self.optionsCombomBox,width=50)
        self.comboBox.pack(side=LEFT)

        #butao que vai accionar o evento de mostar as estatisticas na ttK.tree
        self.showStatisticsButton = Button(self.frameButtons,text ="Just Do It!",width=15, command=self.event_showStatistic)
        self.showStatisticsButton.pack(side=LEFT)

        #array com nome das colunas da tree
        colNames = ["Title0","Title1","Title2"]

        #Criaçao da tree 
        self.tree = ttk.Treeview(self,columns=colNames,height=15)
        #Diminui a coluna #0 a zero porque nao interessa para mostrar a informação
        self.tree.column('#0', width=0,) 
        self.tree.pack(pady=5)

        #Buttao que vai acionar o evento de guardar as estatisticas em formato .csv
        self.saveButton = Button(self,text ="Save",width=25, command=self.evt_saveStatistic)
        self.saveButton.pack()

    def event_showStatistic(self):
        """ Evento que vai por toda a informaçao da estatistica em questao na tk.tree"""
        option = self.comboBox.get()
        self.colNames = ["Title0","Title1","Title2"]

        #Vai limpar a tree sempre que o evento é accionado
        x = self.tree.get_children() 
        for item in x: 
            self.tree.delete(item)

        #Nestes if's qual for a estatistica selecionada vai chamar a estatitisca correspondente a classe satitsticsClass e colocar a informçao na tree
        if option == 'o numero de alunos colocados por instituicao':
            self.statisticsClass.studentsNumberInstitution()

            colNames = ["Código da Instituição","Nome da Instituicão","Numero de colocados"]


            for x in self.statisticsClass.studentsNumberInstitution()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass
            
            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')
           
            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text=colNames[2]) 
               
        elif option == "o numero de alunos colocados por distrito":

            colNames = ["Distritos","Alunos Colocados"]

            for x in self.statisticsClass.studentsNumberDistrict()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass
            
            
            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')

            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text='')

            pass
        elif option == "a permilagem de alunos colocados por distrito":
            colNames = ["Distritos","Permilagem"]

            for x in self.statisticsClass.permilagemStudentsDistrict()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass
            
            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')
            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text='')
            pass
        elif option == 'a percentagem de alunos colocados por instituicao em relacao a todos os alunos colocados':

            colNames = ["Código da Instituição","Nome da Instituicão","% de alunos colocados"]

            for x in self.statisticsClass.percentStudentsNumberInstitution()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass
            
            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')
            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text=colNames[2])
            pass
        elif option == 'o numero de vagas por colocar por instituicao':

            colNames = ["Código da Instituição","Nome da Instituicão","Vagas sobrantes"]

            for x in self.statisticsClass.numberPlacesInstitution()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass

            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')
            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text=colNames[2])
            pass

        elif option == 'o numero de vagas por colocar por distrito':

            colNames = ["Distritos","Vagas por Colocar"]

            for x in self.statisticsClass.numberPlacesDistrict()[1:]:
                self.tree.insert('', 'end', values = [str(i).decode("utf-8") for i in x])
                pass
            #for col in colNames:
            self.tree.column('Title0',anchor='center')
            self.tree.column('Title1',anchor='center')
            self.tree.column('Title2',anchor='center')
            self.tree.heading('Title0', text=colNames[0])
            self.tree.heading('Title1', text=colNames[1])
            self.tree.heading('Title2', text='')
            pass

        pass
    def evt_saveStatistic(self):
        """ evento que vai guardar a estatistica que está selecionada na combox """

        option = self.comboBox.get()

        if option == 'o numero de alunos colocados por instituicao':
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.studentsNumberInstitution(),fileName)
            pass
        elif option == "o numero de alunos colocados por distrito":
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.studentsNumberDistrict(),fileName)
            pass
        elif option == "a permilagem de alunos colocados por distrito":
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.permilagemStudentsDistrict(),fileName)
            pass
        elif option == 'a percentagem de alunos colocados por instituicao em relacao a todos os alunos colocados':
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.percentStudentsNumberInstitution(),fileName)
            pass
        elif option == 'o numero de vagas por colocar por instituicao':
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.numberPlacesInstitution(),fileName)
            pass
        elif option == 'o numero de vagas por colocar por distrito':
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.csv',initialdir='C:\\',title='Save Statistics')
            csvSave().saveStatistics(self.statisticsClass.numberPlacesDistrict(),fileName)
            pass
            



class graphFrame(Frame):
    """ Classe que vai conter a frame que vai mostrar os graficos das estatisticas"""
    def __init__(self, parent, controller):
        Frame.__init__(self, parent)

        #inicializaçao da classe que faz as estatisticas
        self.statisticsClass = statisticsClass()
        #inicializaçao da classe que faz os graficos
        self.graficsClass = makeGraph()

        #Frame que vai conter as combox e o grafico e um botao para gurdar a imagem do grafico em .png
        self.Frame = initFrame(self,controller)
        self.Frame.pack()

        #Frame que contem as combombox, as labels e o botao para gerar o grafico
        self.frameOptionsButtons = Frame(self)
        self.frameOptionsButtons.pack(side=TOP)

        #Label Escolher grafico de Institutos ou Distritos
        self.labelStatistics = Label(self.frameOptionsButtons, text="Grafico de :",font=('times',10, 'bold'))
        self.labelStatistics.pack(side = LEFT)

        #array com as opçoes da primeira combobox
        self.optionsGraphicsCombomBox = ['Institutos','Distritos']

        #Primeira combobox onde escolhe graficos de Institutos os Distritos
        self.graphicComboBox = ttk.Combobox(self.frameOptionsButtons, textvariable="valueOptionsGraphics", width=10 ,state='readonly',values=self.optionsGraphicsCombomBox)
        self.graphicComboBox.pack(side=LEFT)

        #guarda a informaçao das instituiçoes para colocar na combobox para ser selecionveis para gerar o grafico
        self.infonInstitution = self.statisticsClass.getInstitutionsName_and_ID()
        
        #array que contem on nomes dos intitutos para aparecer na segunda combobox
        self.nameGraphicsCombomBox = [self.infonInstitution[x][1] for x in range(len(self.infonInstitution))]
        
        #array que contem  os ids dos institutos
        self.idGraphics = [self.infonInstitution[x][0] for x in range(len(self.infonInstitution))]
        
        #Combobox que tem todos os graficos que se podem fazer por institutos ou distritos
        self.chooseGraphicComboBox = ttk.Combobox(self.frameOptionsButtons, width = 40,textvariable="valueGraphic", state='readonly',postcommand = self.evt_changeValuesComBox)
        self.chooseGraphicComboBox.pack(side=LEFT)


        #Butao que vai acionar o evento de mostrar o grafico para a opçao selecionada nas combombox
        self.showGraphicsButton = Button(self.frameOptionsButtons,text ="Just Do It!",width=10, command=self.evt_makeGraphButton)
        self.showGraphicsButton.pack(side=LEFT)

        #Figura que simula que está um grafico logo quando seleciona a opçao gráficos
        self.f = Figure(figsize=(5,4), dpi=80)

        #Frame que vai conter o gráfico
        self.graphicFrame = Frame(self)
        self.graphicFrame.pack(side=TOP,padx=5, pady=5)

        
        #Canvas que vai adicionar a figura que nao contem gráfico
        self.canvas = FigureCanvasTkAgg(self.f,self.graphicFrame)
        self.canvas.show()
        self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
        self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)

        #Butao que vai acionar o evento para guardar a imagem do gráfico em .png
        self.saveButton = Button(self,text ="Save",width=25, command=self.saveGraph)
        self.saveButton.pack()

    def saveGraph(self):
        """ evento que guarda a imagem do gráfico que ésta a ser mostrado no programa """
        try:
            fileName=tkFileDialog.asksaveasfile(mode='w', defaultextension='.png',initialdir='C:\\',title='Save Statistics')
            self.figureGraph.savefig(fileName)
            tkMessageBox.showinfo("SALVAR", "O FICHEIRO FOI SALVO CORRECTAMENTE :)")
            pass
        except Exception, e:
            tkMessageBox.showinfo("ERRO AO SALVAR", "O FICHEIRO NAO FOI SALVO CORRECTAMENTE")
            raise
        
        pass

    def evt_changeValuesComBox(self):
        """ Evento que vai mudar as opçoes dos graficos a mostrar consuante a opçao selecionada na primeira comboBox"""
        if self.graphicComboBox.get() == "Institutos":
            self.chooseGraphicComboBox['values'] = self.nameGraphicsCombomBox
            pass
            
        if self.graphicComboBox.get() == "Distritos":
            self.chooseGraphicComboBox['values'] = ['o numero de alunos colocados por distrito','a permilagem de alunos colocados por distrito','o numero de vagas por colocar por distrito']
            pass

    def evt_makeGraphButton(self):
        """Evento que vai realizar o gráfico escolhido pelo utlizador"""
        self.figureGraph = None
        if self.graphicComboBox.get() == 'Institutos':
            option = self.chooseGraphicComboBox.get()
            if option != "":
                self.IDinstitution = self.nameGraphicsCombomBox.index(self.chooseGraphicComboBox.get())
        
        
                self.dataGraph = self.statisticsClass.staticsGraphInstitution(self.idGraphics[self.IDinstitution])
                self.figureGraph = self.graficsClass.grapicsInstitution(self.dataGraph)
                pass

        if self.graphicComboBox.get() == 'Distritos':
            option = self.chooseGraphicComboBox.get()

            if option == "o numero de alunos colocados por distrito":
                self.figureGraph = self.graficsClass.graphicsDistrict(self.statisticsClass.studentsNumberDistrict())
            pass
            if option == "a permilagem de alunos colocados por distrito":
                self.figureGraph = self.graficsClass.graphicsDistrict(self.statisticsClass.permilagemStudentsDistrict())
            pass
            if option == "o numero de vagas por colocar por distrito":
                self.figureGraph = self.graficsClass.graphicsDistrict(self.statisticsClass.numberPlacesDistrict())
            pass

        if self.figureGraph != None:

            self.canvas._tkcanvas.destroy()
            self.canvas = FigureCanvasTkAgg(self.figureGraph,self.graphicFrame)
            self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)
            self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1)
        
            pass
        
        
if __name__ == "__main__":

    root = Tk()
    main = main(root)
    root.mainloop()
